package com.knowledge.graph.service.impl;

import com.knowledge.graph.mapper.CourseAndUserMapper;
import com.knowledge.graph.mapper.CourseMapper;
import com.knowledge.graph.mapper.VideoAndCourseMapper;
import com.knowledge.graph.mapper.VideoMapper;
import com.knowledge.graph.model.entity.*;
import com.knowledge.graph.service.CourseService;
import com.knowledge.graph.utils.FileUtils;
import com.knowledge.graph.model.vo.CourseVO;
import com.knowledge.graph.model.vo.ResponseVO;
import com.knowledge.graph.model.vo.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@Service
public class CourseServiceImpl implements CourseService {

    @Value("${my.course.address}")
    private String courseAddress;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private CourseAndUserMapper courseAndUserMapper;

    @Autowired
    private VideoAndCourseMapper videoAndCourseMapper;

    @Autowired
    private VideoMapper videoMapper;

    @Override
    public ResponseVO addCourse(String courseName, MultipartFile courseImage, String courseDescription, Long userID) {
        File imageFile = FileUtils.addFile(courseAddress+File.separator+courseName+userID, courseImage);
        Course course = new Course(courseName,imageFile.getAbsolutePath(),courseDescription,courseAddress+File.separator+courseName+userID);
        courseMapper.insert(course);
        courseAndUserMapper.insert(new CourseAndUser(course.getId(), userID));
        return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(), course);
    }

    @Override
    public ResponseVO updateCourse(Integer courseID, String courseName, MultipartFile courseImage, String courseDescription) {
        Course courseById = courseMapper.selectById(courseID);
        if (!courseImage.isEmpty()) {
            File oldImageFile = new File(courseById.getCourseImage());
            FileUtils.deleteFile(oldImageFile);
            File imageFile = FileUtils.addFile(courseById.getCourseAddress(), courseImage);
            courseById.setCourseImage(imageFile.getAbsolutePath());
        }
        if (!courseName.isEmpty()){
            courseById.setCourseName(courseName);
        }
        if (!courseDescription.isEmpty())
            courseById.setCourseDescription(courseDescription);
        int flag = courseMapper.updateById(courseById);
        if (flag != 1)
            return new ResponseVO(StatusCode.FAIL_UPDATE.getCode(), StatusCode.FAIL_UPDATE.getMessage());
        return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(), courseById);
    }

    @Override
    public ResponseVO deleteCourse(Integer courseID) {
        Course course = courseMapper.selectById(courseID);
        if (null == course)
            return new ResponseVO(StatusCode.FAIL_SELECT.getCode(), StatusCode.FAIL_SELECT.getMessage());
        FileUtils.deleteFile(new File(course.getCourseAddress()));
        courseMapper.deleteById(course);
        courseAndUserMapper.deleteByCourseId(courseID);
        List<Integer> videosID = videoAndCourseMapper.selectByCourseId(courseID);
        for (Integer videoID : videosID) {
            videoMapper.deleteById(videoID);
        }
        videoAndCourseMapper.deleteByCourse(courseID);
        return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
    }

    @Override
    public ResponseVO getCourse(Long userID) throws IOException {
        List<Long> coursesID = courseAndUserMapper.selectByTeacherId(userID);
        List<Course> courses = new ArrayList<>();
        for (Long courseID : coursesID){
            Course course = courseMapper.selectById(courseID);
            courses.add(course);
        }
        List<CourseVO> courseVOS = new ArrayList<>();
        for (Course course:courses) {
            String imageToBase64 = FileUtils.ImageToBase64(course.getCourseImage());
            courseVOS.add(new CourseVO(course,imageToBase64));
        }
        return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(),courseVOS);
    }

    @Override
    public ResponseVO getCourseByID(Integer courseID) throws IOException {
        Course course = courseMapper.selectById(courseID);
        String imageToBase64 = FileUtils.ImageToBase64(course.getCourseImage());
        CourseVO courseVO = new CourseVO(course, imageToBase64);
        return new ResponseVO(StatusCode.SUCCESS.getCode(),StatusCode.SUCCESS.getMessage(),courseVO);
    }

    @Override
    public ResponseVO postCourseOfInvitationCode(Long courseId) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer invitationCode = new StringBuffer();
        for (int i = 0; i < 8; i++) {
            int number = random.nextInt(62);
            invitationCode.append(str.charAt(number));
        }
        Course course = new Course();
        course.setInvitationCode(invitationCode.toString());
        course.setId(courseId);
        int flag = courseMapper.updateById(course);
        if (flag == 1)
            return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
        return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
    }

    @Override
    public ResponseVO createCourseAndUser(String text, User user_state) {
        if (text.isEmpty())
            return new ResponseVO(StatusCode.FAIL_SELECT.getCode(), StatusCode.FAIL_SELECT.getMessage());
        Long queryCouseId = courseMapper.selectByCode(text);
        if (queryCouseId == null)
            return new ResponseVO(StatusCode.FAIL_SELECT.getCode(), StatusCode.FAIL_SELECT.getMessage());
        CourseAndUser courseAndUser = new CourseAndUser();
        courseAndUser.setCourseId(queryCouseId);
        courseAndUser.setUserId(user_state.getId());
        int count = courseAndUserMapper.selectByCourseAndUser(courseAndUser);
        if (count == 1)
            return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
        courseAndUserMapper.insert(courseAndUser);
        return new ResponseVO<>(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
    }

    @Override
    public ResponseVO queryClassByUser(Long userId) throws IOException {
        List<Long> queryCourseIds = courseAndUserMapper.selectByTeacherId(userId);
        List<CourseVO> courseVOList = new ArrayList<>();
        for (Long queryCourseId : queryCourseIds) {
            Course course = courseMapper.selectById(queryCourseId);
            String imageToBase64 = FileUtils.ImageToBase64(course.getCourseImage());
            CourseVO courseVO = new CourseVO(course, imageToBase64);
            courseVOList.add(courseVO);
        }
        return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(), courseVOList);
    }

    @Override
    public List<CourseVO> searchCourseList(String text) throws IOException {
        List<Course> courseList = courseMapper.selectCourseList(text);
        List<CourseVO> courseVOList = new ArrayList<>();
        for (Course course : courseList) {
            CourseVO courseVO = new CourseVO(course, FileUtils.ImageToBase64(course.getCourseImage()));
            courseVOList.add(courseVO);
        }
        return courseVOList;
    }
}
